package com.cl.utility.controller;

import com.alibaba.fastjson.JSONObject;
import com.cl.utility.annocation.NoAuthorization;
import com.cl.utility.constant.Message;
import com.cl.utility.constant.PassInfo;
import com.cl.utility.pojo.ResultCode;
import com.cl.utility.util.ConvertUtils;
import com.cl.utility.util.GenerateUtils;
import com.cl.utility.util.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;

/**
 * @author liddhappy
 * @description token 控制层
 * @createTime 2022/11/26 10:06
 */
@RestController
@RequestMapping("/token")
@Slf4j
public class TokenController {
    @Autowired(required = false)
    private RedisTemplate redisTemplate;

    @GetMapping("/generate")
    @NoAuthorization
    public ResultCode<JSONObject> token(String userName, String password,
                                        String permission) {
        HashMap<String, HashMap<String, PassInfo>> userEntryMap = new HashMap<>();
        HashMap<String, PassInfo> userInfoMap = new HashMap<>();
        String secret = TokenUtils.initBase64SECRET();
        PassInfo passInfo = GenerateUtils.buildPassword(password);
        String sign = TokenUtils.sign(secret, userName, permission);
        this.redisTemplate.opsForValue().set("token", sign);
        this.redisTemplate.opsForValue().set(userName, passInfo);

        passInfo.setPassword(password);
        /**
         * userInfoMap store K sign-> V passInfo
         * sign  store userName and permission
         * passInfo store salt and password
         */
        log.info("token: " + sign);
        log.info("passInfo: " + passInfo);
        userInfoMap.put(sign, passInfo);
        /**
         * secret -> get userName
         * userInfo -> get password
         */
        log.info("HS256 secret: " + secret);
        userEntryMap.put(secret, userInfoMap);
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(userEntryMap));
        return new ResultCode<>(Message.Success(), jsonObject);
    }

    @GetMapping("/verity")
    public ResultCode<String> verityToken(String secret, String password) {
        Object tokenObject = this.redisTemplate.opsForValue().get("token");
        String token = ConvertUtils.convert(tokenObject, String.class);
        if (TokenUtils.verify(secret, token)) {
            String userName = TokenUtils.parseJWT(token);
            log.info("userName:"  + userName);
            PassInfo passInfo = (PassInfo) this.redisTemplate.opsForValue().get(userName);
            GenerateUtils.checkPass(password, passInfo.getSalt(), passInfo.getPassword());
            return new ResultCode<>(Message.Success("user verity success,you can use"), "not data");
        }
        return new ResultCode<>(Message.ERROR("token invalid"), "not data");
    }
}
